# -*- coding: UTF-8 -*-
"""
@author:zhangxing
@file:standardize_field_utils.py
@time:2020/12/14
ReadMe:
    Function:
        check_time_field() 时间检查函数
        check_city_field() 城市检查函数
"""
import time
import re
from datetime import datetime
import unicodedata

all_city_values = {
    "上海": ["上海市", "黄浦区", "徐汇区", "长宁区", "静安区", "普陀区", "虹口区", "杨浦区", "浦东新区", "闵行区", "宝山区", "嘉定区", "金山区", "松江区", "青浦区",
           "奉贤区",
           "崇明区"],
    "北京": ["北京", "密云区", "延庆区", "朝阳区", "丰台区", "石景山区", "海淀区", "门头沟区", "房山区", "通州区", "顺义区", "昌平区", "大兴区", "怀柔区", "平谷区",
           "东城区",
           "西城区"],
    "天津": ["滨海新区", "和平区", "河北区", "河东区", "河西区", "南开区", "红桥区", "东丽区", "西青区", "津南区", "北辰区", "武清区", "宝坻区", "静海区", "宁河区",
           "蓟州区"],
    "重庆": ["万州区", "黔江区", "涪陵区", "渝中区", "大渡口区", "江北区", "沙坪坝区", "九龙坡区", "南岸区", "北碚区", "渝北区", "巴南区", "长寿区", "江津区", "合川区",
           "永川区", "南川区", "綦江区", "大足区", "铜梁区", "璧山区"],
    "河北": ["石家庄市", "保定市", "秦皇岛市", "唐山市", "邯郸市", "邢台市", "沧州市", "承德市", "廊坊市", "衡水市", "张家口市"],
    "山西": ["太原市", "大同市", "阳泉市", "长治市", "临汾市", "晋中市", "运城市", "晋城市", "忻州市", "朔州市", "吕梁市"],
    "内蒙古": ["呼和浩特市", "呼伦贝尔市", "包头市", "赤峰市", "乌海市", "通辽市", "鄂尔多斯市", "乌兰察布市", "巴彦淖尔市"],
    "辽宁": ["沈阳市", "大连市", "盘锦市", "鞍山市", "抚顺市", "本溪市", "铁岭市", "锦州市", "丹东市", "辽阳市", "葫芦岛市", "阜新市", "朝阳市", "营口市"],
    "吉林": ["长春市", "吉林市", "延边朝鲜族自治州", "通化市", "白城市", "四平市", "辽源市", "松原市", "白山市"],
    "黑龙江": ["哈尔滨市", "伊春市", "牡丹江市", "大庆市", "鸡西市", "鹤岗市", "绥化市", "双鸭山市", "七台河市", "佳木斯市", "黑河市", "齐齐哈尔市"],
    "江苏": ["南京市", "昆山市", "泰兴市", "无锡市", "常州市", "扬州市", "徐州市", "苏州市", "连云港市", "盐城市", "淮安市", "宿迁市", "镇江市", "南通市", "泰州市"],
    "浙江": ["杭州市", "宁波市", "绍兴市", "温州市", "湖州市", "嘉兴市", "台州市", "金华市", "舟山市", "衢州市", "丽水市"],
    "安徽": ["合肥市", "芜湖市", "亳州市", "马鞍山市", "池州市", "淮南市", "淮北市", "蚌埠市", "巢湖市", "安庆市", "宿州市", "宣城市", "滁州市", "黄山市", "六安市",
           "阜阳市", "铜陵市", "广德市"],
    "福建": ["福州市", "厦门市", "泉州市", "漳州市", "南平市", "三明市", "龙岩市", "莆田市", "宁德市"],
    "江西": ["南昌市", "赣州市", "景德镇市", "九江市", "萍乡市", "新余市", "抚州市", "宜春市", "上饶市", "鹰潭市", "吉安市"],
    "山东": ["济南市", "荷泽市", "青岛市", "淄博市", "枣庄市", "东营市", "烟台市", "潍坊市", "济宁市", "泰安市", "威海市", "日照市", "滨州市", "德州市", "聊城市",
           "临沂市",
           "菏泽市", "莱芜市", "临沂市"],
    "河南": ["郑州市", "洛阳市", "焦作市", "商丘市", "信阳市", "新乡市", "安阳市", "开封市", "漯河市", "南阳市", "鹤壁市", "平顶山市", "濮阳市", "许昌市", "周口市",
           "三门峡市", "驻马店市"],
    "湖北": ["襄阳市", "荆门市", "武汉市", "恩施土家族苗族自治州", "咸宁市", "襄樊市", "荆州市", "黄石市", "宜昌市", "随州市", "鄂州市", "孝感市", "黄冈市", "十堰市"],
    "湖南": ["长沙市", "郴州市", "湘西土家族苗族自治州", "娄底市", "衡阳市", "株洲市", "湘潭市", "岳阳市", "常德市", "邵阳市", "益阳市", "永州市", "张家界市", "怀化市"],
    "广东": ["江门市", "广州市", "深圳市", "梅州市", "佛山市", "汕头市", "湛江市", "韶关市", "中山市", "珠海市", "茂名市", "肇庆市", "阳江市", "惠州市", "潮州市",
           "揭阳市", "清远市", "河源市",
           "东莞市", "汕尾市", "云浮市"],
    "广西": ["南宁市", "贺州市", "柳州市", "桂林市", "梧州市", "北海市", "玉林市", "钦州市", "百色市", "防城港市", "贵港市", "河池市", "崇左市", "来宾市"],
    "海南": ["海口市", "三亚市", "儋州市", "三沙市", "文昌市"],
    "四川": ["成都市", "阿坝藏族羌族自治州", "甘孜藏族自治州", "凉山彝族自治州", "乐山市", "雅安市", "广安市", "南充市", "自贡市", "泸州市", "内江市", "宜宾市", "广元市",
           "达州市", "资阳市", "绵阳市", "眉山市", "巴中市", "攀枝花市",
           "遂宁市", "德阳市"],
    "贵州": ["贵阳市", "遵义市", "六盘水市", "安顺市", "毕节市", "铜仁市", "黔东南苗族侗族自治州", "黔南布依族苗族自治州", "黔西南布依族苗族自治州"],
    "云南": ["昆明市", "楚雄彝族自治州", "红河哈尼族彝族自治州", "文山壮族苗族自治州", "西双版纳傣族自治州", "大理白族自治州", "德宏傣族景颇族自治州",
           "怒江傈僳族自治州", "迪庆藏族自治州", "普洱市", "思茅市", "玉溪市", "大理市", "曲靖市", "昭通市", "保山市", "丽江市", "临沧市"],
    "西藏": ["拉萨市", "阿里市"],
    "陕西": ["西安市", "甘南藏族自治州", "咸阳市", "榆林市", "宝鸡市", "铜川市", "渭南市", "汉中市", "安康市", "商洛市", "延安市"],
    "甘肃": ["兰州市", "白银市", "武威市", "金昌市", "平凉市", "张掖市", "嘉峪关市", "酒泉市", "庆阳市", "定西市", "陇南市", "天水市"],
    "青海": ["格尔木市", "西宁市", "玉树市", "果洛市", "海东市", "海西市", "海南市", "海北市"],
    "宁夏": ["银川市", "吴忠市", "固原市", "青铜峡市", "石嘴山市", "中卫市"],
    "新疆": ["乌鲁木齐市", "伊犁哈萨克自治州", "克拉玛依市", "克孜勒苏柯尔克孜自治州", "巴音郭楞蒙古自治州", "博尔塔拉蒙古自治州", "昌吉回族自治州"],
    "香港": ["香港岛市", "九龙市", "新界市", "新界西市"],
    "澳门": ["澳门半岛市", "澳门离岛市"],
    "台湾": ["台北市", "高雄市", "基隆市", "台中市", "新竹市", "台南市", "嘉义市", "新北市", "桃园市"]
}


def write_error_file(info):
    with open('./record.log', 'a+', encoding='utf-8') as f:  # 仅供测试记录
        f.write(info)


def load_all_citys() -> list:
    """TODO 可以优化为一个爬虫，定时更新城市列表信息"""
    all_city = []
    for k, v in all_city_values.items():
        for i in v:
            all_city.append(i)
    return all_city


def handle_city(city_name):
    city_name = city_name.strip().replace(' ', '')
    city_name.strip('/').strip('\\')
    city_name = re.sub(r"\d*", "", city_name)
    return city_name


def check_city_field(origin_city_name: str):
    if not origin_city_name:
        return
    city_name = handle_city(origin_city_name)
    if city_name == "省级":
        city_name = None
    else:
        all_city_list = load_all_citys()
        if city_name in all_city_list:
            pass
        elif city_name + '市' in all_city_list:
            city_name = city_name + '市'
        elif city_name + '区' in all_city_list:
            city_name = city_name + '区'
        else:
            city_name = None
            info = f"\033[32mWarnning\033[0m: city检测字段：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} 输入记录：【  {origin_city_name} 】未通过校验\n"
            print(info)
            write_error_file(info)
    return city_name


def get_current_date():
    date_string = datetime.now().strftime('%Y-%m-%d')
    return date_string


def get_current_datetime():
    date_time_string = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    return date_time_string


def pretreatment(string):
    """
        前处理
    """
    string = unicodedata.normalize('NFKC', str(string).strip('').strip('/').strip('-').strip('#'))  # 处理空格/#
    str2null = [',', '.']  # 未包括中间的空格，2020/12/07 10:10:10 或10:10:10 2020/12/07
    for obj in str2null:
        string = string.replace(obj, '')
    string = string.replace("  ", " ") if "  " in string else string
    if ":" in string:  # 默认以空格划分
        datetime_list = string.split(" ")
        flag = 1
        while flag:
            for obj in datetime_list[::-1]:
                if ":" in obj or not obj:
                    datetime_list.remove(obj)
                if len(datetime_list) == 1:
                    string = datetime_list[0]
                    flag = 0
                if '/' in obj or "年" in obj or "月" in obj or "日" in obj:
                    string = obj
    return string


def deal_character(string):
    """
    处理类似：2020年12月3日
    处理汉字逻辑，
        1)判断含有哪些汉字：年/月/日，是否都含有
        2)判断是否是年月日的顺序
    未考虑：三月二十四日 这种（三/二十四）不是数字的情况
    """
    character_list = ['年', '月', '日']
    return_string = ''
    for obj in character_list:
        regex = rf'(\d*){obj}'
        result = re.findall(regex, string)
        if result:
            digit_str = result[0]
            if len(digit_str) == 1:
                digit_str = '0' + digit_str
            return_string += digit_str + "-"
        elif obj == "日":
            print(f"\033[32m输入数据中不含有具体日期，已默认为1日\033[0m")
            return_string += "01"
        else:
            raise Exception(f"输入数据不合法，不含有{obj}份，call for help")
    return return_string if return_string[-1] != '-' else return_string[:-1]


def deal_slash(string):
    """
        类似：2020/1/23
        处理斜杠:/
        数据要求：年份是4位，并且月一定在日之前
        如下情况未考虑：19/03/25
    """
    flag = 1
    date_list = string.strip('/').split('/')
    if len(date_list) != 3:
        raise Exception(f"输入数据有误 {string},/分隔后未找到3个元素")
    return_string = ''
    for obj in date_list:
        if len(obj) == 4:
            return_string = obj + "-" + return_string
            flag = 0
        elif len(obj) == 1:
            return_string += "0" + obj + "-"
        else:
            return_string += obj + "-"
    if flag:
        raise Exception(f"输入数据有误 {string},未定位到年份")
    return return_string if return_string[-1] != '-' else return_string[:-1]


def deal_short_horizontal_line(string):
    """
        类似：2020-1-23
        处理短横：-
    """
    flag = 1
    date_list = string.strip('-').split('-')
    if len(date_list) != 3:
        raise Exception(f"输入数据有误 {string},-分隔后未找到3个元素")
    return_string = ''
    for obj in date_list:
        if len(obj) == 4:
            return_string = obj + "-" + return_string
            flag = 0
        elif len(obj) == 1:
            return_string += "0" + obj + "-"
        else:
            return_string += obj + "-"
    if flag:
        raise Exception(f"输入数据有误 {string},未定位到年份")
    return return_string if return_string[-1] != '-' else return_string[:-1]


def deal_pure_digit(string):
    """
        处理类似：20201123
    """
    return string[0:4] + '-' + string[4:6] + '-' + string[6:8]


def is_valid_date(str_date):
    """
        判断是否是一个有效的日期字符串:    2001-02-29 会报错
    """
    time.strptime(str_date, "%Y-%m-%d")
    return True


def check_time_field(string):
    pretreatment_str = pretreatment(string)
    if '/' in pretreatment_str:
        date_string = deal_slash(pretreatment_str)
    elif '-' in pretreatment_str:
        date_string = deal_short_horizontal_line(pretreatment_str)
    elif "年" in pretreatment_str or '月' in pretreatment_str or '日' in pretreatment_str:
        date_string = deal_character(pretreatment_str)
    elif pretreatment_str.isdigit():
        date_string = deal_pure_digit(pretreatment_str)
    try:
        if is_valid_date(date_string):
            return date_string
    except:
        pass
        print(f"\033[32m请联系管理员处理\033[0m\n\033[31m待处理字段【 {string} 】\033[0m")
        # info = f"\033[32mWarnning\033[0m: 时间字段：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} 输入记录：【  {string} 】未通过校验\n"
        # print(info)
        # write_error_file(info)
        # raise Exception(info)


if __name__ == "__main__":
    print("********************************************************1")
    print(get_current_date())
    print(get_current_datetime())
    print(check_time_field('2020年11月2日3 18:20:18'))

    print("********************************************************2")
    print(check_city_field('浦东新区'))
    print(check_city_field('浦东新'))
    print(check_city_field('扬州'))
    print(check_city_field('扬州市'))
    print(check_city_field('省级'))
    print(check_city_field('江苏'))
    print(check_city_field('南京市'))
    print(check_city_field('南京市区'))
    print(check_city_field('江苏省'))
    # test
    # 浦东新区
    # 浦东新区
    # 扬州市
    # 扬州市
    # None
    # None
    # None
